/*
 * @Author: 杨鑫鑫 m14775611609@163.com
 * @Date: 2025-07-15 00:17:15
 * @LastEditors: 杨鑫鑫 m14775611609@163.com
 * @LastEditTime: 2025-07-27 18:53:48
 * @FilePath: /the-c--standard-library/Code/CHAPTER3_INITALIZER_LIST.cpp
 * @Description:
 *
 * Copyright (c) 2025 by 杨鑫鑫, Xiao Bi Software Company ,All Rights Reserved.
 */

 


 /*
 
notepad++ 卡死了，系统重装了。
//with mutable a lambda  becomes stateful even if the state is passed by value.
//Without mutable .which is usual case,operator() becomes  a constant member function
//SO only read access to objects that were passed by value.
#include<iostream>
#include<functional>

int main()
{
	int id = 0;
	int id2 = 0;
	auto f = [=] ()  mutable {
		std::cout<<"id = "<<id <<"\tid2 = "<<id2 <<std::endl;
		++id;//OK
		++id2;//OK
	};

	id = 43;
	f();
	f();
	f();
	f();
	
	std::cout<<"FINAL id = "<<id <<std::endl;
	
	return 0;
}

id = 0	id2 = 0
id = 1	id2 = 1
id = 2	id2 = 2
id = 3	id2 = 3
FINAL id = 43
*/

/*
#include<iostream>
#include<functional>

int main()
{
	int id = 0;
	auto f = [id] ()  {
		std::cout<<"id = "<<id <<std::endl;
		++id;//OK
	};
	
	id = 43;
	f();
	f();
	f();
	f();
	
	std::cout<<"FINAL id = "<<id <<std::endl;
	
	return 0;
}
//ERROR      Compile 

CHAPTER3_INITALIZER_LIST.cpp: In lambda function:
CHAPTER3_INITALIZER_LIST.cpp:20:19: error: increment of read-only variable ‘id’
   20 |                 ++id;//OK
      |                   ^~
*/
 /*
#include<iostream>
#include<functional>

int main()
{
	int id = 0;
	auto f = [id] () mutable {
		std::cout<<"id = "<<id <<std::endl;
		++id;//OK
	};
	
	id = 43;
	f();
	f();
	f();
	f();
	
	std::cout<<"FINAL id = "<<id <<std::endl;
	
	return 0;
}
id = 0
id = 1
id = 28
id = 3
FINAL id = 43
*/
 
/*
#include <iostream>
using namespace std;
int x = 8;
int y = 43;
int main()
{
    int x = 999999;
    auto valueorreference_lambda = [x, &y]()
    {
        cout << "[valueorreference_lambda]===========x = " << x << endl;
        cout << "[valueorreference_lambda]===========y = " << y << endl;
        ++y;
        cout << "[AFTER ADD][valueorreference_lambda]===========x = " << x << endl;
        cout << "[valueorreference_lambda]===========y = " << y << endl;
    };
    cout << "===========x = " << x << endl; // 0
    cout << "===========y = " << y << endl; // 43
    x = y = 77;

    cout << "===========x = " << x << endl; // 77
    cout << "===========y = " << y << endl; // 77

    valueorreference_lambda(); //
    valueorreference_lambda();
    cout << "===========x = " << x << endl;
    cout << "===========y = " << y << endl;
}
===========x = 999999
===========y = 43
===========x = 77
===========y = 77
[valueorreference_lambda]===========x = 999999
[valueorreference_lambda]===========y = 77
[AFTER ADD][valueorreference_lambda]===========x = 999999
[valueorreference_lambda]===========y = 78
[valueorreference_lambda]===========x = 999999
[valueorreference_lambda]===========y = 78
[AFTER ADD][valueorreference_lambda]===========x = 999999
[valueorreference_lambda]===========y = 79
===========x = 77
===========y = 79
*/

/*
#include <iostream>
using namespace std;
int x = 8;
int y = 43;
int main()
{
 
    auto valueorreference_lambda = [x, &y]()
    {
        cout << "[valueorreference_lambda]===========x = " << x << endl;
        cout << "[valueorreference_lambda]===========y = " << y << endl;
        ++y;
        cout << "[AFTER ADD][valueorreference_lambda]===========x = " << x << endl;
        cout << "[valueorreference_lambda]===========y = " << y << endl;
    };
    cout << "===========x = " << x << endl; // 0
    cout << "===========y = " << y << endl; // 43
    x = y = 77;

    cout << "===========x = " << x << endl; // 77
    cout << "===========y = " << y << endl; // 77

    valueorreference_lambda(); //
    valueorreference_lambda();
    cout << "===========x = " << x << endl;
    cout << "===========y = " << y << endl;
}
===========x = 8
===========y = 43
===========x = 77
===========y = 77
[valueorreference_lambda]===========x = 77
[valueorreference_lambda]===========y = 77
[AFTER ADD][valueorreference_lambda]===========x = 77
[valueorreference_lambda]===========y = 78
[valueorreference_lambda]===========x = 77
[valueorreference_lambda]===========y = 78
[AFTER ADD][valueorreference_lambda]===========x = 77
[valueorreference_lambda]===========y = 79
===========x = 77
===========y = 79
*/
/*
#include <iostream>
using namespace std;

int main()
{
    int x = 8;
    int y = 43;
    auto valueorreference_lambda = [x, &y]()
    {
        cout << "[valueorreference_lambda]===========x = " << x << endl;
        cout << "[valueorreference_lambda]===========y = " << y << endl;
        ++y;
        cout << "[AFTER ADD][valueorreference_lambda]===========x = " << x << endl;
        cout << "[valueorreference_lambda]===========y = " << y << endl;
    };
    cout << "===========x = " << x << endl; // 0
    cout << "===========y = " << y << endl; // 43
    x = y = 77;

    cout << "===========x = " << x << endl; // 77
    cout << "===========y = " << y << endl; // 77

    valueorreference_lambda(); //
    valueorreference_lambda();
    cout << "===========x = " << x << endl;
    cout << "===========y = " << y << endl;
}
===========x = 8
===========y = 43
===========x = 77
===========y = 77
[valueorreference_lambda]===========x = 8
[valueorreference_lambda]===========y = 77
[AFTER ADD][valueorreference_lambda]===========x = 8
[valueorreference_lambda]===========y = 78
[valueorreference_lambda]===========x = 8
[valueorreference_lambda]===========y = 78
[AFTER ADD][valueorreference_lambda]===========x = 8
[valueorreference_lambda]===========y = 79
===========x = 77
===========y = 79
*/
/*
#include <iostream>
using namespace std;

int main()
{
    int x = 8;
    int y = 43;
    auto valueorreference_lambda = [&x, &y]()
    {
        cout << "[valueorreference_lambda]===========x = " << x << endl;
        cout << "[valueorreference_lambda]===========y = " << y << endl;
        ++y;
        cout << "[AFTER ADD][valueorreference_lambda]===========x = " << x << endl;
        cout << "[valueorreference_lambda]===========y = " << y << endl;
    };
    cout << "===========x = " << x << endl; // 0
    cout << "===========y = " << y << endl; // 43
    x = y = 77;

    cout << "===========x = " << x << endl; // 77
    cout << "===========y = " << y << endl; // 77

    valueorreference_lambda(); //
    valueorreference_lambda();
    cout << "===========x = " << x << endl;
    cout << "===========y = " << y << endl;
}


===========x = 8
===========y = 43
===========x = 77
===========y = 77
[valueorreference_lambda]===========x = 77
[valueorreference_lambda]===========y = 77
[AFTER ADD][valueorreference_lambda]===========x = 77
[valueorreference_lambda]===========y = 78
[valueorreference_lambda]===========x = 77
[valueorreference_lambda]===========y = 78
[AFTER ADD][valueorreference_lambda]===========x = 77
[valueorreference_lambda]===========y = 79
===========x = 77
===========y = 79
*/

/*
#include <iostream>
#include <string>
using namespace std;

// just return int 42

int main()
{
    // show nothing

    auto dob = [] () -> double  {
        return 42.0;
    };
    cout<<dob()<<endl;
    return 0;
}
*/
/*
#include <iostream>
#include <string>
using namespace std;

auto l = [](const std::string &s)
{ cout << "[s]=" << s << endl; };

int main()
{
   l("THis is a parentheses parameters");
   return 0;
}

[s]=THis is a parentheses parameters
*/
/*
#include<iostream>

using namespace std;

//define a lambda
auto print_hello_lambda = [] {cout<<"hello it's local lambda"<<endl;};
int main()
{
    //and using *() to call it,
    print_hello_lambda();

    [] {
        cout <<"Hello lambda"<<endl;
    } ();


}

hello it's local lambda
Hello lambda*/
/*
#include <iostream>
#include <bitset>
using namespace std;

void print()
{
    cout << "[NO TEMPLATE PRINT ]" << endl;
}

template <typename T, typename... Types>
void print(const T &firstArgs, const Types &...remainArgs)
{
    cout << "[VARIADIC TEMPLATE]" << firstArgs << endl;
    print(remainArgs...);
}

int main()
{
    print(100, 2.3, -200, "hello print", std::bitset<16>(366), 45);
    return 0;
}

// [VARIADIC TEMPLATE]100
// [VARIADIC TEMPLATE]2.3
// [VARIADIC TEMPLATE]-200
// [VARIADIC TEMPLATE]hello print
// [VARIADIC TEMPLATE]0000000101101110
// [VARIADIC TEMPLATE]45
// [NO TEMPLATE PRINT ]
*/

/*
#include <iostream>
#include <bitset>
using namespace std;

template <typename T>
void print(const T &arg)
{
    cout << "[NOVARIADIC TEMPLATE]" << arg << endl;
}

template <typename T, typename... Types>
void print(const T &firstArgs, const Types &...remainArgs)
{
    cout << "[VARIADIC TEMPLATE]" << firstArgs << endl;
    print(remainArgs...);
}

int main()
{
    print(100, 2.3, -200, "hello print", std::bitset<16>(366), 45);
    return 0;
}*/
// [VARIADIC TEMPLATE]100
// [VARIADIC TEMPLATE]2.3
// [VARIADIC TEMPLATE]-200
// [VARIADIC TEMPLATE]hello print
// [VARIADIC TEMPLATE]0000000101101110
// [NOVARIADIC TEMPLATE]45

// NO PRINT NON-TEMPLATE

/*#include<iostream>
#include<bitset>
using namespace std;

void print()
{
    //cout<<"This is a single no para printf()"<<endl;
    //return;
}

template<typename T, typename... Types>
void print(const T& firstArg, const Types&... remainArgs)
{
    cout<<firstArg<<std::endl;
    print(remainArgs...);//call print() for remaining arguments.
}

int main()
{
    print(100,2.3,-200,"hello print",std::bitset<16>(366),45);
    return 0;
}
100
2.3
-200
hello print
0000000101101110
45*/
/*
#include<iostream>
#include<bitset>
using namespace std;

void print()
{
    cout<<"This is a single no para printf()"<<endl;
    return;
}

template<typename T, typename... Types>
void print(const T& firstArg, const Types&... remainArgs)
{
    cout<<firstArg<<std::endl;
    print(remainArgs...);//call print() for remaining arguments.
}

int main()
{
    print(100,2.3,-200,"hello print",std::bitset<16>(366),45);
    return 0;
}
// 100
// 2.3
// -200
// hello print
// 0000000101101110
// 45
// This is a single no para printf()
//--------------------------
*/
// To end the recusion the non-template overload of print() is provided.

/*
An rvalue reference is a reference and returning it while referring to a local object means that you
return a reference to an object that doesn't exist anymore.
Whether std::move() is used doesn't matter.
#include <iostream>
#include <utility>

class X
{
public:
   X()
   {
       std::cout << "DEFAULT CONSTRUCTOR" << std::endl;
   }
};

X&& foo()
{
   X x;
   return std::move(x);// X don't have to and should not move() return values.
   //An rvalue reference is a reference and returning it while referring to a local object means that you
   //return a reference to an object that doesn't exist anymore.
}

int main()
{
   X a =foo();
   return 0;
}
//DEFAULT CONSTRUCTOR
*/
/*
#include <iostream>
#include <utility>

class X
{
public:
    X()
    {
        std::cout << "DEFAULT CONSTRUCTOR" << std::endl;
    }
};

X&& foo()
{
    X x;
    return x;
    //returns reference to nonexisting object
    //cannot bind rvalue reference of type ‘X&&’ to lvalue of type ‘X’
}

int main()
{
    X a =foo();
    return 0;
}*/
/*
#include <iostream>
#include <utility>

class X
{
public:
    X()
    {
        std::cout << "DEFAULT CONSTRUCTOR" << std::endl;
    }
    X(X&&) =delete;
};

X foo()
{
    X x;
    return std::move(x); //don't have to and should not move() return values.
    //use of deleted function ‘X::X(X&&)’
}

int main()
{
    X a =foo();
    return 0;
}*/
/*
#include <iostream>
#include <utility>

class X
{
public:
    X()
    {
        std::cout << "DEFAULT CONSTRUCTOR" << std::endl;
    }
    X(const X&) = delete;
};

X foo()
{
    X x;
    return x;
    //use of deleted function ‘X::X(const X&)’
}

int main()
{
    X a =foo();
    return 0;
}*/
/*
#include <iostream>
#include <utility>

class X
{
public:
   X()
   {
       std::cout << "DEFAULT CONSTRUCTOR" << std::endl;
   }
   X(const X& x)
   {
       std::cout << "COPY CONSTRUCTOR" << std::endl;
   }

   X(X&& x)
   {
       std::cout << "MOVE CONSTRUCTOR" << std::endl;
   }
};

X foo()
{
   X x;
   return x;
}

int main()
{
   X a =foo();
   // don't have to and should not move() return values.
   return 0;
}
//DEFAULT CONSTRUCTOR
*/
/*//  If you implement
//   void foo(const X&)
//   without void foo(X&&),the behavior is as in C++98:foo() can be called for rvalues and for lvalues.
#include <iostream>
#include <utility>

class X
{
public:
    X()
    {
        std::cout << "X default constructor called." << std::endl;
    }
    X(const X &)
    {
        std::cout << "X copy constructor called." << std::endl;
    }
    X(X &&) noexcept
    {
        std::cout << "X move constructor called." << std::endl;
    }
};

void foo(const X &x)
{
    std::cout << "foo called with lvalue reference." << std::endl;
}

int main()
{
    X x1;
    std::cout << "----------------------" << std::endl;
    foo(x1);//lvalue reference
    // cannot bind rvalue reference of type ‘X&&’ to lvalue of type ‘X’
    std::cout << "----------------------" << std::endl;
    foo(X()); // rvalue reference
    std::cout << "----------------------" << std::endl;
    foo(std::move(x1)); // rvalue reference
    std::cout << "----------------------" << std::endl;
    return 0;
}
*/

// X default constructor called.
// ----------------------
// foo called with lvalue reference.
// ----------------------
// X default constructor called.
// foo called with lvalue reference.
// ----------------------
// foo called with lvalue reference.
// ----------------------
/*
* If you implement
 void foo(X&);
 void foo(X&&);
or
 void foo(const X&);
 void foo(X&&);

The version for rvalues is allowed to and should provide move semantics.

#include <iostream>
#include <utility>

class X
{
public:
    X()
    {
        std::cout << "X default constructor called." << std::endl;
    }
    X(const X &)
    {
        std::cout << "X copy constructor called." << std::endl;
    }
    X(X &&)
    noexcept
    {
        std::cout << "X move constructor called." << std::endl;
    }
};

void foo( X &x)
{
    std::cout << "foo called with lvalue reference." << std::endl;
}

void foo(X &&x)
{
    std::cout << "foo called with rvalue reference." << std::endl;
}

int main()
{
    X x1;
    std::cout << "----------------------" << std::endl;
    foo(x1);//lvalue reference
    std::cout << "----------------------" << std::endl;
    foo(X()); // rvalue reference
    std::cout << "----------------------" << std::endl;
    foo(std::move(x1)); // rvalue reference
    std::cout << "----------------------" << std::endl;
    return 0;
}
// X default constructor called.
// ----------------------
// foo called with lvalue reference.
// ----------------------
// X default constructor called.
// foo called with rvalue reference.
// ----------------------
// foo called with rvalue reference.
// ----------------------
*/
/*
If you implement
 void foo(X&& )
  but neither void foo(X&) not void foo(const X&),foo() can be called on rvalues,but trying to call it on lvalue with trigger a compile error,
#include<iostream>
#include<utility>

class X{
    public:
    X() {
        std::cout << "X default constructor called." << std::endl;
    }
    X(const X&) {
        std::cout << "X copy constructor called." << std::endl;
    }
    X(X&&) noexcept{
        std::cout << "X move constructor called." << std::endl;
    }
};


void foo(X&& x){
    std::cout << "foo called with rvalue reference." << std::endl;
}


int main()
{
    X x1;
    std::cout<<"----------------------"<<std::endl;
    //foo(x1);//lvalue reference
    //cannot bind rvalue reference of type ‘X&&’ to lvalue of type ‘X’
    std::cout<<"----------------------"<<std::endl;
    foo(X());//rvalue reference
    std::cout<<"----------------------"<<std::endl;
    foo(std::move(x1));//rvalue reference
    std::cout<<"----------------------"<<std::endl;
    return 0;
}
X default constructor called.
----------------------
foo called with lvalue reference.
----------------------
X default constructor called.
foo called with rvalue reference.
----------------------
foo called with rvalue reference.
----------------------
/*
//STRING 6 basic member functions
#include<iostream>
#include<cstring>
class String{
    private:
        char *data;
    public:
        //default constructor
        String(const char *str = nullptr) {
            if(str == nullptr) {
                data = new char[1];
                *data = '\0';
            } else {
                size_t length = std::strlen(str) + 1;
                data = new char[length];
                std::strncpy(data, str, length);
            }
            std::cout<< "String constructor called." << std::endl;
        }

        //destructor
        ~String(){
            std::cout<< "String destructor called." << std::endl;
            delete[] data;
        }

        //copy constructor式结束后，临时对象会被销毁，其析构函数会释放临时对象的资
        String(const String  &lvalue){
            std::cout<< "String copy constructor called." << std::endl;
            size_t length = std::strlen(lvalue.data) + 1;
            data = new char[length];// 若能加 NULL 判断则更好
            std::strncpy(data, lvalue.data, length);
        }


        //move constructor
        String(String &&rvalue) noexcept :data(rvalue.data) {
            std::cout<< "String move constructor called." << std::endl;
            rvalue.data = nullptr;
        }

        //copy assignment operator
        String& operator= (const String &lvalue) {
            std::cout<< "String copy assignment operator called." << std::endl;
            if(this != &lvalue) {
                delete[] data;
                size_t length = std::strlen(lvalue.data)+1;
                data = new char[length];
                std::strncpy(data,lvalue.data,length);
            }
            return *this;
        }

        //move assignment operator
        String& operator=(String&& rvalue) noexcept{
            std::cout<<"String move assignment operator called." << std::endl;
            if(this != &rvalue) {
                delete[] data;
                data = rvalue.data;//transfer ownership
                rvalue.data = nullptr;
            }
            return *this;
        }

        //print function
        void print() const {
            if(data) {
                std::cout << "String value: " << data << std::endl;
            } else {
                std::cout << "String is empty." << std::endl;
            }
        }
};

int main()
{
    //String a,b,c;
    //a = b; // 如果返回对象本身，会调用拷贝构造函数
    //test the String class
    String str1;
    String str2("Hello world!");
    String str3 = str2;
    String str4 = std::move(str2);
    str1 = str3;
    str1 = std::move(str4);
    str1.print(); // Should print "Hello world!"
    str2.print(); // Should indicate that str2 is empty
    str3.print(); // Should print "Hello world!"
    str4.print(); // Should indicate that str4 is empty
    return 0;
}
//

 #include <iostream>
#include <utility> // for std::move

class Resource {
private:
    int* data;

public:
    // 构造函数
    Resource(int value) : data(new int(value)) {}

    // 移动构造函数
    Resource(Resource&& other) noexcept : data(other.data) {
        other.data = nullptr; // 清理源对象
    }

    // 移动赋值运算符
    Resource& operator=(Resource&& other) noexcept {
        if (this != &other) {
            delete data;       // 释放当前对象的资源
            data = other.data; // 转移资源
            other.data = nullptr; // 清理源对象
        }
        return *this;
    }

    // 析构函数
    ~Resource() {
        delete data;
    }

    void print() const {
        if (data) {
            std::cout << "Resource value: " << *data << std::endl;
        } else {
            std::cout << "Resource is empty" << std::endl;
        }
    }
};

int main() {
    Resource res1(42);
    Resource res2(100);

    res2 = std::move(res1); // 移动赋值

    res1.print(); // 输出：Resource is empty
    res2.print(); // 输出：Resource value: 42

    return 0;
}

#include <iostream>
#include <utility>

class Resource
{
private:
    int *data;
public:
    // Default constructor
    Resource(int value):data(new int(value)) {
        std::cout<<"Resource Default constructor called."<<std::endl;
        std::cout << "Resource acquired with value: " << *data << std::endl;
    }

    //move constructor
    Resource(Resource &&other) noexcept:data(other.data){
        std::cout<<"Resource Move constructor called."<<std::endl;
        other.data = nullptr;//clear the other resource

    }

    //move assignment operator
    Resource & operator=( Resource && rvalue) noexcept{
        std::cout<<"Resource Move assignment operator called."<<std::endl;
        if(this != &rvalue) {
            //*data = 111 this =0x7fffffffdaf0
            delete data;//release the current resources
            data = rvalue.data;//transfer ownership
            rvalue.data = nullptr;
        }
        return *this;
    }
    //destructor
    ~Resource(){
        std::cout<<"Resource Destructor called."<<std::endl;
        delete data; // release the resource
    }

    void print() const {
        std::cout << "Resource print function called." << std::endl;
        if (data) {
            std::cout << "Resource value: " << *data << std::endl;
        } else {
            std::cout << "Resource is empty." << std::endl;
        }
    }

};

int main()
{
    Resouroperatorce res1(100);
    Resource res2(111);

    res2 = std::move(res1);

    res1.print(); // Should indicate that res1 is empty
    res2.print(); // Should show the value 100
    return 0;
}

#include <iostream>
#include <list>
#include <initializer_list>

using namespace std;

class P
{
public:
   // construct
   P(const int &x, const int &y)
   {
       cout << "[CALL GENERAL] FUNCTIONS." << endl;
       cout << "[x] = " << x << "[y] = " << y << endl;
   }

   explicit P(const std::initializer_list<int> &lists)
   {
       cout << "[CALL INITIALIZER] FUNCTIONS." << endl;
       for (const auto &p : lists)
       {
           cout << p << endl;
       }
   }
};

int main()
{
   cout << "Beginning of main()" << endl;

   // TEST CODES.
   P p(55, 66);
   P q{55, 66};
   P u{55, 66, 77};
   //  P s = {556,90};//CANNOT COMPILE SUCCESSFULLY/
   long sum = 0;

   long int array[] = {1, 2, 3, 4, 5, 6};
   for (int x : array)
   {
       sum+= x;
   }
   cout<< "sum = "<<sum<<endl;
}
*/
// Beginning of main()
// [CALL GENERAL] FUNCTIONS.
// [x] = 55[y] = 66
// [CALL INITIALIZER] FUNCTIONS.
// 55
// 66
// [CALL INITIALIZER] FUNCTIONS.
// 55
// 66
// 77
